package com.bu.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import org.springframework.stereotype.Service;

import com.bu.model.Problem;
import com.bu.model.Topic;

/**
 * @author xueqiang.mi
 * @since 2011-2-21
 */
@Service
public class ProblemService {

	public void add(Problem obj) {
		PersistenceManager pm = PMF.get();
		try {
			obj.setCrtDate(new Date());
			pm.makePersistent(obj);
			String[] topics = obj.getTopics().split(",");
			for (int i = 0; i < topics.length; i++) {
				String topic = topics[i].trim();
				if (null == topic || "".equals(topic)) {
					continue;
				}

				Topic t = null;
				try {
					t = pm.getObjectById(Topic.class, topic);
				} catch (Exception e) {
					// Ignore
				}
				if (t == null) {
					t = new Topic(topic, i);
				}
				if (t.getLevel() == 0) { // add sub topic when processing root topic
					for (int j = 1; j < topics.length; j++) {
						t.getChildren().add(topics[j].trim());
					}
				}
				t.getProblems().add(obj.getId());
				pm.makePersistent(t);
			}
		} finally {
			pm.close();
		}
	}

	public void delete(Long id) {
		PersistenceManager pm = PMF.get();
		try {
			Problem p = pm.getObjectById(Problem.class, id);
			if (p != null) {
				String[] topics = p.getTopics().split(",");
				for (String topic : topics) {
					Topic t = pm.getObjectById(Topic.class, topic.trim());
					t.getProblems().remove(p.getId());
				}
				pm.deletePersistent(p);
			}
		} finally {
			pm.close();
		}
	}

	public Problem get(Long id) {
		PersistenceManager pm = PMF.get();
		try {
			return pm.getObjectById(Problem.class, id);
		} finally {
			pm.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<Problem> list() {
		PersistenceManager pm = PMF.get();
		try {
			Query q = pm.newQuery(Problem.class);
			Collection<Problem> c = pm.detachCopyAll((Collection<Problem>) q.execute());
			return new ArrayList<Problem>(c);
		} finally {
			pm.close();
		}
	}

	public Collection<Problem> listByTopic(String topic) {
		Set<Problem> result = new TreeSet<Problem>(new Comparator<Problem>() {
			@Override
			public int compare(Problem o1, Problem o2) {
				return o1.getId().compareTo(o2.getId());
			}
		});
		PersistenceManager pm = PMF.get();
		try {
			Topic t = pm.getObjectById(Topic.class, topic);
			if (!t.getProblems().isEmpty()) {
				Set<Long> removed = new HashSet<Long>();
				for (Long id : t.getProblems()) {
					try {
						result.add(pm.getObjectById(Problem.class, id));
					} catch (Exception e) { // the problem may be deleted before
						e.printStackTrace();
						removed.add(id);
					}
				}
				if (!removed.isEmpty()) { // remove the problems which have been deleted
					t.getProblems().removeAll(removed);
				}
			}
			return result;
		} finally {
			pm.close();
		}
	}
}
